package com.showcai.util;


import com.showcai.tools.ToolsBase;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;

public class DateUtil extends ToolsBase {

    /**
     * 日期格式： yyyyMM
     **/
    public static final String DATE_TIME_YYYYMM = "yyyyMM";
    /**
     * 日期格式： yyyy-MM
     **/
    public static final String DATE_TIME_YYYY_MM = "yyyy-MM";
    /**
     * 日期格式： MMdd
     **/
    public static final String DATE_TIME_MMdd = "MMdd";
    /**
     * 日期格式： yyyy-MM-dd HH:mm:ss
     **/
    public static final String DATE_TIME = "yyyy-MM-dd HH:mm:ss";
    /**
     * 日期格式： yyy-MM-dd HH:mm
     **/
    public static final String DATE_TIME_NO_SS = "yyyy-MM-dd HH:mm";
    /**
     * 日期格式：yyyyMMddHHmmss
     **/
    public static final String DATE_TIME_NO = "yyyyMMddHHmmss";
    /**
     * 日期格式：yyyy-MM-dd
     **/
    public static final String DATE = "yyyy-MM-dd";
    /**
     * 日期格式：dd/MM/yyyy
     **/
    public static final String DATE2 = "dd/MM/yyyy";
    /**
     * 日期格式：yyyyMMdd
     **/
    public static final String DATE3 = "yyyyMMdd";
    /**
     * 日期格式： MM月dd日
     **/
    public static final String DATE4 = "MM月dd日";
    /**
     * 日期格式：yyyy年MM月dd日 HH:mm:ss
     **/
    public static final String DATE5 = "yyyy年MM月dd日 HH:mm:ss";
    /**
     * HHmmss
     **/
    public static final String TIME_HHmmss = "HHmmss";
    /**
     * HH:mm:ss
     **/
    public static final String TIME = "HH:mm:ss";
    /**
     * HH:mm
     **/
    public static final String TIME2 = "HH:mm";
    private static final String[] weekDays = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
    /**
     * 有关日期工具类(extends TimeUtil)
     * <p>
     * TimeUtil主要功能有： 1.各种日期类型（字符，util.Date，sql.Date，Calendar等）转换
     * 2.获取指定日期的年份，月份，日份，小时，分，秒，毫秒 3.获取当前/系统日期(指定日期格式) 4.获取字符日期一个月的天数
     * 5.获取指定月份的第一天,最后一天
     * <p>
     * DateUtil主要功能有： 1.日期比较 2.获取2个字符日期的天数差，周数差，月数差，年数差 3.日期添加 4.判断给定日期是不是润年
     */

    // ---当前日期的年，月，日，时，分，秒
    public static Calendar now = Calendar.getInstance();
    int year = now.get(Calendar.YEAR);
    int date = now.get(Calendar.DAY_OF_MONTH);
    int month = now.get(Calendar.MONTH) + 1;
    int hour = now.get(Calendar.HOUR);
    int min = now.get(Calendar.MINUTE);
    int sec = now.get(Calendar.SECOND);

    /**
     * 获取一个月的天数
     *
     * @return
     */
    public static Integer getDaysForMonth(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);

        Integer maxDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
        return maxDay;
    }

    /**
     * 获取一个月的最后一天
     *
     * @return
     */
    public static Date getLastDayForMonth(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);

        Integer maxDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
        cal.set(Calendar.DAY_OF_MONTH, maxDay);
        return cal.getTime();
    }

    /**
     * 获取一个月的第一天
     *
     * @return
     */
    public static Date getFirstDayForMonth(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);

        cal.set(Calendar.DAY_OF_MONTH, 1);
        return cal.getTime();
    }

    /**
     * 将短时间格式时间转换为字符串 yyyy-MM-dd
     *
     * @param dateDate
     * @return
     */
    public static String dateToStr(Date dateDate) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        String dateString = formatter.format(dateDate);
        return dateString;
    }

    /**
     * 格式化时间
     *
     * @param date
     * @param format 格式化样式
     * @return
     */
    public static String dateToStr(Date date, String format) {
        if (null == date) {
            return null;
        }
        SimpleDateFormat sformat = new SimpleDateFormat(format);
        return sformat.format(date);
    }

    /**
     * 将长时间格式时间转换为字符串 yyyy-MM-dd HH:mm:ss
     *
     * @param dateDate
     * @return
     */
    public static String dateToStrLong(Date dateDate) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateString = formatter.format(dateDate);
        return dateString;
    }

    /**
     * 字符串转换成日期
     *
     * @param str
     * @return date
     */
    public static Date strToDate(String str) {
        if (str == null || "".equals(str))
            return null;
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = null;
        try {
            date = format.parse(str);
        } catch (ParseException e) {
            format = new SimpleDateFormat("yyyy-MM-dd");
            try {
                date = format.parse(str);
            } catch (ParseException e1) {
                try {
                    date = format.parse(str);
                } catch (ParseException e2) {
                    logger.error("转化时间格式异常:" + str);
                }
            }
        }
        return date;
    }

    /**
     * 字符串转换成日期
     *
     * @param str
     * @return date
     */
    public static Date strToDate(String str, String dataFormat) {

        if (str == null || "".equals(str))
            return null;
        SimpleDateFormat format = new SimpleDateFormat(dataFormat);
        Date date = null;
        try {
            date = format.parse(str);
        } catch (ParseException e) {
            System.out.println("字符串转换成日期异常:" + str);
        }
        return date;
    }

    /**
     * util.Date型日期转化指定格式的字符串型日期
     *
     * @param p_utilDate Date
     * @param p_format   String 格式1:"yyyy-MM-dd" 格式2:"yyyy-MM-dd hh:mm:ss EE"
     *                   格式3:"yyyy年MM月dd日 hh:mm:ss EE" 说明: 年-月-日 时:分:秒 星期 注意MM/mm大小写
     * @return String
     * @Author:
     * @Date: 2006-10-31
     */
    public static String toStrDateFromUtilDateByFormat(Date p_utilDate, String p_format)
            throws ParseException {
        String l_result = "";
        if (p_utilDate != null) {
            SimpleDateFormat sdf = new SimpleDateFormat(p_format);
            l_result = sdf.format(p_utilDate);
        }
        return l_result;
    }

    // -----------------获取指定日期的年份，月份，日份，小时，分，秒，毫秒----------------------------

    /**
     * 获取指定日期的年份
     *
     * @param p_date util.Date日期
     * @return int 年份
     * @author zhuqx
     * @Date: 2006-10-31
     */
    public static int getYearOfDate(Date p_date) {
        Calendar c = Calendar.getInstance();
        c.setTime(p_date);
        return c.get(Calendar.YEAR);
    }

    /**
     * 获取指定日期的月份
     *
     * @param p_date util.Date日期
     * @return int 月份
     * @author zhuqx
     * @Date: 2006-10-31
     */
    public static int getMonthOfDate(Date p_date) {
        Calendar c = Calendar.getInstance();
        c.setTime(p_date);
        return c.get(Calendar.MONTH) + 1;
    }

    /**
     * 获取指定日期的日份
     *
     * @param p_date util.Date日期
     * @return int 日份
     * @author zhuqx
     * @Date: 2006-10-31
     */
    public static int getDayOfDate(Date p_date) {
        Calendar c = Calendar.getInstance();
        c.setTime(p_date);
        return c.get(Calendar.DAY_OF_MONTH);
    }

    public static int getLastDayOfMonth(Date p_date) {
        Calendar c = Calendar.getInstance();
        c.setTime(p_date);
        return c.getActualMaximum(Calendar.DAY_OF_MONTH);
    }

    /**
     * 获取指定日期的小时
     *
     * @param p_date util.Date日期
     * @return int 日份
     * @author zhuqx
     * @Date: 2006-10-31
     */
    public static int getHourOfDate(Date p_date) {
        Calendar c = Calendar.getInstance();
        c.setTime(p_date);
        return c.get(Calendar.HOUR_OF_DAY);
    }

    /**
     * 获取指定日期的分钟
     *
     * @param p_date util.Date日期
     * @return int 分钟
     * @author zhuqx
     * @Date: 2006-10-31
     */
    public static int getMinuteOfDate(Date p_date) {
        Calendar c = Calendar.getInstance();
        c.setTime(p_date);
        return c.get(Calendar.MINUTE);
    }

    /**
     * 获取指定日期的秒钟
     *
     * @param p_date util.Date日期
     * @return int 秒钟
     * @author zhuqx
     * @Date: 2006-10-31
     */
    public static int getSecondOfDate(Date p_date) {
        Calendar c = Calendar.getInstance();
        c.setTime(p_date);
        return c.get(Calendar.SECOND);
    }

    /**
     * 获取指定日期的毫秒
     *
     * @param p_date util.Date日期
     * @return long 毫秒
     * @author zhuqx
     * @Date: 2006-10-31
     */
    public static long getMillisOfDate(Date p_date) {
        Calendar c = Calendar.getInstance();
        c.setTime(p_date);
        return c.getTimeInMillis();
    }

    /**
     * 在给定的日期基础上添加年，月，日、时，分，秒 例如要再2006－10－21（uitl日期）添加3个月，并且格式化为yyyy-MM-dd格式，
     * 这里调用的方式为 addDate(2006－10－21,3,Calendar.MONTH,"yyyy-MM-dd")
     *
     * @param p_startDate 给定的日期
     * @param p_count     时间的数量
     * @param p_field     添加的域
     * @param p_format    时间转化格式，例如：yyyy-MM-dd hh:mm:ss 或者yyyy-mm-dd等
     * @return 添加后格式化的时间
     * @Date: 2006-10-31
     */
    public static String addDate(Date p_startDate, int p_count, int p_field, String p_format) throws ParseException {

        // 年，月，日、时，分，秒
        int l_year = getYearOfDate(p_startDate);
        int l_month = getMonthOfDate(p_startDate) - 1;
        int l_day = getDayOfDate(p_startDate);
        int l_hour = getHourOfDate(p_startDate);
        int l_minute = getMinuteOfDate(p_startDate);
        int l_second = getSecondOfDate(p_startDate);
        Calendar l_calendar = new GregorianCalendar(l_year, l_month, l_day, l_hour, l_minute, l_second);
        l_calendar.add(p_field, p_count);
        return toStrDateFromUtilDateByFormat(l_calendar.getTime(), p_format);
    }

    /**
     * 计算两个日期之间相差的天数
     *
     * @param smdate 较小的时间
     * @param bdate  较大的时间
     * @return 相差天数
     * @throws ParseException
     */
    public static int daysBetween(Date smdate, Date bdate) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        smdate = sdf.parse(sdf.format(smdate));
        bdate = sdf.parse(sdf.format(bdate));
        Calendar cal = Calendar.getInstance();
        cal.setTime(smdate);
        long time1 = cal.getTimeInMillis();
        cal.setTime(bdate);
        long time2 = cal.getTimeInMillis();
        long between_days = (time2 - time1) / (1000 * 3600 * 24);

        return Integer.parseInt(String.valueOf(between_days));
    }

    /**
     * 计算两个日期之间相差的小时数
     *
     * @param smdate 较小的时间
     * @param bdate  较大的时间
     * @return 相差小时数
     * @throws ParseException
     */
    public static int hoursBetween(Date smdate, Date bdate) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat(DateUtil.DATE_TIME);
        smdate = sdf.parse(sdf.format(smdate));
        bdate = sdf.parse(sdf.format(bdate));
        Calendar cal = Calendar.getInstance();
        cal.setTime(smdate);
        long time1 = cal.getTimeInMillis();
        cal.setTime(bdate);
        long time2 = cal.getTimeInMillis();
        long between_hours = (time2 - time1) / (1000 * 3600);
        return Integer.parseInt(String.valueOf(between_hours));
    }

    public static Date truncateDay(Date date) {
        return DateUtils.truncate(date, Calendar.DAY_OF_MONTH);
    }

    public static Date addDay(Date currDate) {
        if (null == currDate)
            return new Date();
        return DateUtils.addDays(currDate, 1);
    }

    public static Date addDay(Date currDate, int day) {
        if (null == currDate)
            return new Date();
        return DateUtils.addDays(currDate, day);
    }

    public static Date addMonth(Date date) {
        if (null == date)
            return new Date();
        return DateUtils.addMonths(date, 1);
    }

    public static Date addMonth(Date date, int month) {
        if (null == date)
            return new Date();
        return DateUtils.addMonths(date, month);
    }

    public static Date getDayEnd(Date date) {
        if (null == date)
            return null;

        return parseDate(format(date, DATE) + " 23:59:59", DATE_TIME);
    }

    public static Date addMinutes(Date queryDate, Integer add) {
        return DateUtils.addMinutes(queryDate, add);
    }

    public static Date addHour(Date queryDate) {
        return addHour(queryDate, 1);
    }

    public static Date addHour(Date queryDate, Integer add) {
        return DateUtils.addHours(queryDate, add);
    }

    public static Integer getYear(Date queryDate) {
        Integer year = -1;
        if (null == queryDate) {
            return year;
        }
        String yearString = DateFormatUtils.format(queryDate, "yyyy");
        try {
            year = Integer.parseInt(yearString);
        } catch (Exception e) {
        }
        return year;
    }

    public static Integer getMonth(Date queryDate) {
        Integer mon = 1;
        if (null == queryDate) {
            return mon;
        }
        String monString = DateFormatUtils.format(queryDate, "MM");
        try {
            mon = Integer.parseInt(monString);
        } catch (Exception e) {
        }
        return mon;
    }

    public static Integer getDay(Date queryDate) {
        Integer day = 1;
        if (null == queryDate) {
            return day;
        }
        String dayString = DateFormatUtils.format(queryDate, "dd");
        try {
            day = Integer.parseInt(dayString);
        } catch (Exception e) {
        }
        return day;
    }

    public static String getWeekOfDate(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (w < 0)
            w = 0;
        return weekDays[w];
    }

    public static String format(Date date, String dateFormat) {
        return DateFormatUtils.format(date, dateFormat);
    }

    public static Date parseDate(String strDate, String dateFormat) {
        if (null == strDate)
            return null;

        Date parseDate = null;
        try {
            parseDate = DateUtils.parseDate(strDate, new String[]{dateFormat});
        } catch (Exception e) {
            e.printStackTrace();
        }
        return parseDate;
    }

    public static String getDateNickName(Date date) {
        Date today = truncateDay(new Date());
        Date tomorrow = addDay(today);
        Date afterTom = addDay(tomorrow);
        Date now = truncateDay(date);
        if (now.getTime() == today.getTime())
            return "今天";
        if (now.getTime() == tomorrow.getTime())
            return "明天";
        if (now.getTime() == afterTom.getTime())
            return "后天";
        return getWeekOfDate(date);
    }

    public static Long timeDifference(Date dateStrat, Date dateEnd) {
        Long diff = dateStrat.getTime() - dateEnd.getTime();
        return diff;
    }

    public static Long secondDifference(Date dateStrat, Date dateEnd) {// 两个日期之间相差的秒数
        Long diff = (dateStrat.getTime() - dateEnd.getTime()) / 1000;
        return diff;
    }

    public static Long dayDifference(Date dateStrat, Date dateEnd) {// 两个日期之间相差的天数
        Long diff = (dateStrat.getTime() - dateEnd.getTime()) / 86400000;
        return diff;
    }

    public static String getDateByHour(Date dateStrat) {
        System.out.println("dateStrat" + dateStrat);
        int year = getYearOfDate(dateStrat);
        int month = getMonthOfDate(dateStrat);
        int day = getDayOfDate(dateStrat);
        int hour = getHourOfDate(dateStrat);
        System.out.println("year:" + year + "month" + month + "day" + day);
        String dateStr = year + "-" + month + "-" + day + " " + hour + ":00:00";
        System.out.println("dateStr:" + dateStr);
        return dateStr;

    }

    /**
     * 日期转时间戳
     *
     * @param date
     * @return
     */
    public static Long DateToTimeStemp(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal.getTimeInMillis();
    }

    public static void main(String[] args) {
        // Date queryDate = DataUtil.strToDate("2015-04-13 10:02:12",
        // DATE_TIME);
        // System.out.println(DataUtil.dateToStrLong(queryDate));
        // Date date = parseDate("1972-02-01", DATE);
        // System.out.println(getLastDayOfMonth(date));
        // Date startTime = null;
        // try {
        // startTime = DateUtil.strToDate(DateUtil.addDate(new Date(), 1,
        // Calendar.HOUR, DateUtil.DATE_TIME));
        // } catch (ParseException e) {
        // // TODO Auto-generated catch block
        // e.printStackTrace();
        // }
        // startTime = DateUtil.strToDate(DateUtil.getDateByHour(startTime));
        // System.out.println("startTime:" + startTime);S
        // Long sleepTime = DateUtil.timeDifference(startTime, new Date());
        // System.out.println("sleepTime==>" + sleepTime);
        // String dateStr = "2015-04-06 00:00:00";
        // // 1437582189903
        // // Calendar cal = Calendar.getInstance();
        // // cal.setTime(new Date());
        // // long timestamp = cal.getTimeInMillis();
        // // String dd = timestampToDate(dateStr);
        //
        // Long dd = DateToTimestamp(strToDate(dateStr));
        // System.out.println("))))))))))" + dd);
        // dd = DateToTimestamp(new Date());
        // System.out.println("))))))))))" + dd);
        // // 1397577600
        // SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        // String date = sdf.format(new Date(1270483200 * 1000));
        // System.out.println(date);
        // System.out.println(strToDate(dateStr).getTime() +
        // "rrrrrrrrrrrrrrrddddddddddddddddddddddddddddd"
        // + DateToTimeStemp(strToDate(dateStr)));

        // Date date1 = new Date();
        // Date date2 = DateUtil.strToDate("2015-07-31 23:59:59",
        // DateUtil.DATE_TIME);
        // Long expireSecond = DateUtil.secondDifference(date2, date1);
        // System.out.println(expireSecond);
        // System.out.println(DateUtil.timeDifference(date2, date1));
        // System.out.println(DateUtil.dayDifference(date2, date1));

        //-System.out.println(getDayOfDate(new Date()));

        SimpleDateFormat sdf = new SimpleDateFormat("MMM d, yyyy K:m:s a", Locale.ENGLISH);
        Date d2 = null;
        try {
            d2 = sdf.parse("Sep 19, 2018 12:00:00 AM");

        } catch (ParseException e) {
            e.printStackTrace();
        }
        Date d3 = new Date();

    }

    /**
     * Date类型转换为10位时间戳
     *
     * @param time
     * @return
     */
    public static Long DateToTimestamp(Date time) {
        Timestamp ts = new Timestamp(time.getTime());

        return (Long) ((ts.getTime()) / 1000);
    }

    /**
     * 比较日期前后 date > date2 则返回 1 date < date2 则返回 -1 date = date2 则返回 0
     *
     * @param date
     * @param date2
     * @return
     */
    public static int compareDate(Date date, Date date2) {
        if (date.after(date2)) {
            return 1;
        }
        if (date.before(date2))
            return -1;

        return 0;
    }


}
